﻿#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StarFox.ScreenComponents;
#endregion

namespace StarFox.Graphics
{
    #region Types

    /// <summary>
    /// Stores parameter values for a directional light source.
    /// </summary>
    public class DirectionalLight
    {
        /// <summary>
        /// Gets or sets the direction of the light.
        /// </summary>
        public Vector3 Direction { get; set; }
        /// <summary>
        /// Gets or sets the diffuse color of the light.
        /// </summary>
        public Vector3 DiffuseColor { get; set; }
        /// <summary>
        /// Gets or sets the specular color of the light.
        /// </summary>
        public Vector3 SpecularColor { get; set; }
    }

    #endregion

    /// <summary>
    /// Performs configuration of the effects associated with the meshes of a model.
    /// </summary>
    public class EffectProcessor
    {
        #region Properties

        /// <summary>
        /// Gets or sets the product of world, view and projection matrices.
        /// </summary>
        public Matrix WorldViewProjection { get; set; }

        /// <summary>
        /// Gets or sets the world matrix.
        /// </summary>
        public Matrix World { get; set; }

        /// <summary>
        /// Gets or sets the inverse transpose of the world matrix. 
        /// </summary>
        public Matrix WorldInvTrans { get; set; }

        /// <summary>
        /// Gets or sets the camera position.
        /// </summary>
        public Vector3 CameraPosition { get; set; }

        /// <summary>
        /// Gets or sets the transparency level.        
        /// </summary>
        public float Alpha { get; set; }

        /// <summary>
        /// Gets or sets the ambient light color.
        /// </summary>
        public Vector3 AmbientLightColor { get; set; }

        /// <summary>
        /// Gets or sets the TextureCube used for environmental mapping.
        /// </summary>
        public TextureCube ReflectMap { get; set; }

        /// <summary>
        /// Gets the first associated DirectionalLight.
        /// </summary>
        public DirectionalLight DirectionalLight0 { get; private set; }

        /// <summary>
        /// Gets the second associated DirectionalLight.
        /// </summary>
        public DirectionalLight DirectionalLight1 { get; private set; }

        /// <summary>
        /// Gets the third associated DirectionalLight.
        /// </summary>
        public DirectionalLight DirectionalLight2 { get; private set; }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        public EffectProcessor()
        {
            DirectionalLight0 = new DirectionalLight();
            DirectionalLight1 = new DirectionalLight();
            DirectionalLight2 = new DirectionalLight();

            Alpha = 1.0f;
        }

        #endregion

        #region Effects

        /// <summary>
        /// Sets parameter values for the current Effect.
        /// </summary>
        /// <param name="effect">Current Effect.</param>
        public void SetEffectParameters(Effect effect)
        {
            if (effect.Parameters["WorldViewProjection"] != null)
                effect.Parameters["WorldViewProjection"].SetValue(WorldViewProjection);

            if (effect.Parameters["World"] != null)
                effect.Parameters["World"].SetValue(World);

            if (effect.Parameters["WorldInvTrans"] != null)
                effect.Parameters["WorldInvTrans"].SetValue(WorldInvTrans);

            if (effect.Parameters["CameraPosition"] != null)
                effect.Parameters["CameraPosition"].SetValue(CameraPosition);

            if (effect.Parameters["Alpha"] != null)
                effect.Parameters["Alpha"].SetValue(Alpha);

            if (effect.Parameters["AmbientLight"] != null)
                effect.Parameters["AmbientLight"].SetValue(AmbientLightColor);

            if (effect.Parameters["ReflectMap"] != null)
                effect.Parameters["ReflectMap"].SetValue(ReflectMap);

            if (effect.Parameters["DirLight0Direction"] != null)
                effect.Parameters["DirLight0Direction"].SetValue(DirectionalLight0.Direction);

            if (effect.Parameters["DirLight1Direction"] != null)
                effect.Parameters["DirLight1Direction"].SetValue(DirectionalLight1.Direction);

            if (effect.Parameters["DirLight2Direction"] != null)
                effect.Parameters["DirLight2Direction"].SetValue(DirectionalLight2.Direction);

            if (effect.Parameters["DirLight0DiffuseColor"] != null)
                effect.Parameters["DirLight0DiffuseColor"].SetValue(DirectionalLight0.DiffuseColor);

            if (effect.Parameters["DirLight1DiffuseColor"] != null)
                effect.Parameters["DirLight1DiffuseColor"].SetValue(DirectionalLight1.DiffuseColor);

            if (effect.Parameters["DirLight2DiffuseColor"] != null)
                effect.Parameters["DirLight2DiffuseColor"].SetValue(DirectionalLight2.DiffuseColor);

            if (effect.Parameters["DirLight0SpecularColor"] != null)
                effect.Parameters["DirLight0SpecularColor"].SetValue(DirectionalLight0.SpecularColor);

            if (effect.Parameters["DirLight1SpecularColor"] != null)
                effect.Parameters["DirLight1SpecularColor"].SetValue(DirectionalLight1.SpecularColor);

            if (effect.Parameters["DirLight2SpecularColor"] != null)
                effect.Parameters["DirLight2SpecularColor"].SetValue(DirectionalLight2.SpecularColor);
        }

        #endregion
    }
}
